package com.dongnao.network.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.util.CharsetUtil;

//ChannelInboundHandlerAdapter:这是一个基础的入站处理器，你需要手动管理资源的释放。它的 channelRead 方法接收到的消息需要你自己负责释放
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelRegistered");
        super.channelRegistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelActive");
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelInactive");
        super.channelInactive(ctx);
    }

    //读取数据
    /*
    1. ChannelHandlerContext ctx:上下文对象，含有管道pipeline，通道channel，地址
    2. Object msg:就是客户端发送的数据默认 Object
    */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("服务器读取线程 " + Thread.currentThread().getName());
        System.out.println("server上下文对象 " + ctx);
        System.out.println("看看channel 和 pipeline 的关系");//相互包含，你中有我我中有你
        Channel channel = ctx.channel();
        ChannelPipeline pipeline = channel.pipeline();
        ChannelPipeline pipeline2 = ctx.pipeline();//l本质是一个双向链接，出站入站
        System.out.println("pipeline是否同一个：" + (pipeline == pipeline2));
        Channel channel1 = pipeline.channel();
        ChannelHandler handler = ctx.handler();//就是此Channel Handler，this

        //将 msg 转成一个 ByteBuf
        //ByteBuf是 Netty提供的，不是NIO的 ByteBuffer.
        ByteBuf buf = (ByteBuf) msg;
        System.out.println("客户端发送的消息: " + buf.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址: " + channel.remoteAddress());

        ctx.fireChannelRead(msg);//将数据向下一个handler传递
    }

    //数据读取完毕
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        System.out.println("channelReadComplete " + System.currentTimeMillis());

        //writeAndFlush是 write + flush
        //将数据写入缓存并刷新
        //一般要对发送数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello 客户端酱~", CharsetUtil.UTF_8));

        ctx.fireChannelReadComplete();
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelWritabilityChanged");
        super.channelWritabilityChanged(ctx);
    }

    //异常处理
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        ctx.close();
    }
}
